#ifndef __FRAMEWORK_H__
#define __FRAMEWORK_H__

// MACROS
#define glClearColor3v(f) glClearColor((f)[0], (f)[1], (f)[2], 0.0)

#include <GL/glut.h>
#include <string>
#include <GL/freeglut.h>
#include <iostream>
#include <vector>

class IFrameworkCallbacks{
	public:
		IFrameworkCallbacks(){}
		virtual ~IFrameworkCallbacks(){}


		virtual void init(){}
		virtual void redisplay()=0;
		virtual void timer(int value){}
		virtual void reshape(int oldW,int oldH,int w,int h){}
		virtual void keyboard(unsigned char key,int x ,int y){}
		virtual void specKeyboard(int key,int x ,int y){}
		virtual void mousePressed(int key,int state,int x ,int y){}
		virtual void mouseMotion(int x ,int y){}
		virtual void mouseEntry(int state){}
		virtual void mousePassiveMotion(int x,int y){}
};

class Framework{
	private:
		IFrameworkCallbacks* callbacks;
		int windowHeight;
		int windowWidth;
		int windowX;
		int windowY;
		int window;
		std::string caption;
		std::string path;
		bool timerSet;
		unsigned int msecTimer;

		int frame;
		int time;
		int timebase;
		float _fps;
		bool _fpsCalc;

		bool fscreen;

	public:
		~Framework();

		static Framework& instance();

		static void display();
		static void reshape(int w, int h);

		static void keyboard(unsigned char key,int x,int y);
		static void specialFunc(int key,int x ,int y);
		static void mouseFunc(int button,int state,int x ,int y);
		static void mouseMotion(int x ,int y);

		static void mouseEntryFunc(int state);

		static void mousePassiveMotion(int x,int y);

		static void timer(int value);

		bool isTimerSet();
		unsigned int getTimerMsec();
		void setTimer(unsigned int msec);
		void unsetTimer();

		void setWindowDimensions(int windowHeigth,int windowWidth,int windowX,int windowY);
		void setClearColor(float r,float g,float b);
		void setCaption(const std::string& caption);

		void setCallbacks(IFrameworkCallbacks* callbacks);

		void redisplay();
		int getWindow();

		float getWindowWidth();

		float getWindowHeight();

		std::string getPath();

		void fpsCalc(bool state);

		bool fpsCalc();

		bool fullscreen();

		float fps();

		void mainLoop(int argc,char** argv);

		void exit();
	private:
		Framework();

		Framework(const Framework& framework);
		void operator=(const Framework& framework);

		IFrameworkCallbacks* getCallbacks(){ return callbacks; }

		void getOptions(int argc,char** argv);
};

class OptionsParser{
	private:
		std::vector<std::string> parameters;

	public:
		void fillParameters(int argc,char** argv);
		bool isInParameters(std::string tag);
		void getParamValue(std::string tag,std::string& val);
};

#endif // __FRAMEWORK_H__
